#if defined OS_LINUX

#include <pthread.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <dirent.h>
#include <time.h>

#endif

#include "../include/workflow.h"
#include "Base/lib/lib.hashtable.h"
#include "Base/lib/lib.log.h"

static hTab *p_htab_wf_plugin;

BOOL loadWFlowPlugin_EX(const char* const pluginPath){
	return loadWFlowPlugin(pluginPath,p_htab_wf_plugin);
}
/** \brief
	Be aware this function cannot be reenterent.
 *
 * \param const char * const pluginPath
 * \param p_htab_wf_plugin hTab**
 * \return static BOOL
 *
 */

BOOL loadWFlowPlugin(const char * const pluginPath, hTab **p_htab_wf_plugin){

#ifdef OS_LINUX
    DIR *dir;
    struct dirent *dEntry;
#endif

	ASSERT(pluginPath!=NULL);
    ASSERT(p_htab_wf_plugin!=NULL);

#ifdef OS_LINUX
    dir=NULL;

    if (NULL==(dir=opendir(pluginPath))) {
        logIt(LOG_ERROR,"WorkFlow ERROR-Open plugin folder failed");
        return FALSE;
    }

    dEntry=NULL;

	if(NULL==(*p_htab_wf_plugin=initHashTable(100))){
		logIt(LOG_ERROR,"WorkFlow ERROR- Intializing hTab for workflow failed.");
		closedir(dir);
		return FALSE;
	}

    while (NULL!=(dEntry=readdir(dir))) {
        static char pluginSoPath[MAX_LENGTH_OF_FILELOCATION];
        static DIR *dpSo;
        static taskchainPlugin *tcp;

        /*Check for empty folder*/
        if (0==dEntry->d_ino)
            continue;
        if (!strcmp(dEntry->d_name,".")||!strcmp(dEntry->d_name,".."))
            continue;

        memset(pluginSoPath,'\0',MAX_LENGTH_OF_FILELOCATION);

        sprintf(pluginSoPath,"%s/%s.so",pluginPath,dEntry->d_name);
        if (NULL==(tcp=(taskchainPlugin *)malloc(sizeof(taskchainPlugin)))) {
            logIt(LOG_ERROR,"Work FLow - Load \"%s\"failed, cannot malloc pluginItem for it.",dEntry->d_name);
            continue;
        }
        if(NULL==(tcp->pluginName=(char*)(malloc(sizeof(char)*sizeof(dEntry->d_name))))){
            FREEUP(tcp);
            continue;
        }
        strcpy(tcp->pluginName,dEntry->d_name);

        if(NULL==(tcp->handle=dlopen(pluginSoPath, RTLD_LAZY))) {
            FREEUP(tcp->pluginName);
            //FREEUP(tcp->tcp);
            logIt(LOG_ERROR,"Load \"%s\" failed, cannot open the .so file for it. The system will startup without it.",dEntry->d_name);
            continue;
        }
        putHashItem(*p_htab_wf_plugin,tcp->pluginName,(void *)tcp);
        /* */
    }
    return TRUE;

    #endif
}

void freePluginContent(void *content){
    taskchainPlugin *tcp=(taskchainPlugin *)content;
    FREEUP(tcp->pluginName);
    dlclose(tcp->handle);
}

hTab *getWorkFlowPlugin(){
	return p_htab_wf_plugin;
}
BOOL freeWorkFlowPlugin(hTab *p_tab){
    return freeHashTable(p_tab,1,freePluginContent);
}
